// 引入创建slice和异步的方法
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'

// 调用创建异步的方法
export const asyncTodo = createAsyncThunk('asyncAdd', () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      // 由于是为了练习异步,所以把添加功能做成异步的方式.所以添加时,用户输入的任务名其实在异步中根本就无法获取.所以resolve中写的内容无所谓,所以可以不写
      resolve()
    }, 2000)
  })
})

// 创建slice
export default createSlice({
  name: 'todoList', // slice的名称,action对象的type中作为前缀
  initialState: {
    // 初始数据
    todos: [{ id: 1, todoName: '吃饭', isDone: true }],
    editId: undefined, // 注意:如果初始值是undefined,则在redux调试工具中不显示
    isloading: false, // 是否正在执行异步操作. true表示正在执行,false表示异步完成
  },
  // reducer函数和actionCreator
  reducers: {
    // 添加任务
    addTodo(state, action) {
      // 根据任务名创建任务对象
      const todo = {
        id: state.todos.length ? state.todos[state.todos.length - 1].id + 1 : 1,
        todoName: action.payload,
        isDone: false,
      }
      // 将新的任务对象添加到todos中
      state.todos.push(todo)
    },

    // 修改editId
    setEditId(state, action) {
      state.editId = action.payload
    },

    // 修改任务名
    setTodoName(state, action) {
      // 要传递过来两个参数: 1. 被修改的任务对象的id 2. 新的任务名
      const { id, todoName } = action.payload
      // 遍历找到要修改的任务,然后修改任务名
      state.todos.forEach((item) => {
        if (item.id === id) item.todoName = todoName
      })
    },
  },

  // 监听异步,异步成功之后,要添加新的任务
  extraReducers(builder) {
    builder.addCase(asyncTodo.pending, (state, action) => {
      // 知道异步正在执行,展示`正在添加...`的效果
      state.isloading = true
    })
    builder.addCase(asyncTodo.rejected, (state, action) => {
      // 知道异步失败了,隐藏`正在添加...`的效果
      state.isloading = false
    })
    builder.addCase(asyncTodo.fulfilled, (state, action) => {
      // 异步成功之后会触发这个函数,如果异步成功之后需要修改redux数据,则可以在这里进行
      //修改
      // 根据任务名创建任务对象
      const todo = {
        id: state.todos.length ? state.todos[state.todos.length - 1].id + 1 : 1,
        todoName: action.meta.arg, //action.meta.arg获取的是执行异步用户传入的数据
        isDone: false,
      }
      // 将新的任务对象添加到todos中
      state.todos.push(todo)

      // 隐藏`正在加载...`
      state.isloading = false
    })
  },
})
